home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / exec / allocpooled.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  3KB  |  149 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: allocpooled.c,v 1.4 1996/08/13 13:55:58 digulla Exp $
  4.     $Log: allocpooled.c,v $
  5.     Revision 1.4  1996/08/13 13:55:58  digulla
  6.     Replaced __AROS_LA by __AROS_LHA
  7.     Replaced some __AROS_LH*I by __AROS_LH*
  8.     Sorted and added includes
  9.  
  10.     Revision 1.3  1996/08/01 17:41:05  digulla
  11.     Added standard header for all files
  12.  
  13.     Desc:
  14.     Lang:
  15. */
  16. #include "exec_intern.h"
  17. #include <aros/libcall.h>
  18. #include "machine.h"
  19. #include "memory.h"
  20.  
  21. /*****************************************************************************
  22.  
  23.     NAME */
  24.     #include <exec/memory.h>
  25.     #include <clib/exec_protos.h>
  26.  
  27.     __AROS_LH2(APTR, AllocPooled,
  28.  
  29. /*  SYNOPSIS */
  30.     __AROS_LHA(APTR,  poolHeader, A0),
  31.     __AROS_LHA(ULONG, memSize,    D0),
  32.  
  33. /*  LOCATION */
  34.     struct ExecBase *, SysBase, 118, Exec)
  35.  
  36. /*  FUNCTION
  37.     Allocate memory out of a private memory pool.
  38.  
  39.     INPUTS
  40.     poolHeader - Handle of the memory pool
  41.     memSize    - Number of bytes you want to get
  42.  
  43.     RESULT
  44.     A pointer to the number of bytes you wanted or NULL if the memory
  45.     couldn't be allocated
  46.  
  47.     NOTES
  48.  
  49.     EXAMPLE
  50.  
  51.     BUGS
  52.  
  53.     SEE ALSO
  54.     CreatePool(), DeletePool(), FreePooled()
  55.  
  56.     INTERNALS
  57.  
  58.     HISTORY
  59.     16-10-95    created by M. Fleischer
  60.  
  61. ******************************************************************************/
  62. {
  63.     __AROS_FUNC_INIT
  64.  
  65.     APTR ret;
  66.     struct Pool *pool=(struct Pool *)poolHeader;
  67.  
  68.     /* If the memSize is bigger than the ThreshSize allocate seperately. */
  69.     if(memSize>pool->ThreshSize)
  70.     {
  71.     ULONG size;
  72.     struct Block *bl;
  73.  
  74.     /* Get enough memory for the memory block including the header. */
  75.     size=memSize+BLOCK_TOTAL;
  76.     bl=(struct Block *)AllocMem(size,pool->Requirements);
  77.  
  78.     /* No memory left */
  79.     if(bl==NULL)
  80.         return NULL;
  81.  
  82.     /* Initialize the header */
  83.     bl->Size=size;
  84.  
  85.     /* Add the block to the BlockList */
  86.     AddHead((struct List *)&pool->BlockList,(struct Node *)&bl->Node);
  87.  
  88.     /* Set pointer to allocated memory */
  89.     ret=(UBYTE *)bl+BLOCK_TOTAL;
  90.     }else
  91.     {
  92.     struct MemHeader *mh;
  93.  
  94.     /* Follow the list of MemHeaders */
  95.     mh=(struct MemHeader *)pool->PuddleList.mlh_Head;
  96.     for(;;)
  97.     {
  98.         /* Are there no more MemHeaders? */
  99.         if(mh->mh_Node.ln_Succ==NULL)
  100.         {
  101.         /* Get a new one */
  102.         mh=(struct MemHeader *)
  103.            AllocMem(pool->PuddleSize+MEMHEADER_TOTAL,pool->Requirements);
  104.  
  105.         /* No memory left? */
  106.         if(mh==NULL)
  107.             return NULL;
  108.  
  109.         /* Initialize new MemHeader */
  110.         mh->mh_First=(struct MemChunk *)((UBYTE *)mh+MEMHEADER_TOTAL);
  111.         mh->mh_First->mc_Next=NULL;
  112.         mh->mh_First->mc_Bytes=pool->PuddleSize;
  113.         mh->mh_Lower=mh->mh_First;
  114.         mh->mh_Upper=(UBYTE *)mh->mh_First+pool->PuddleSize;
  115.         mh->mh_Free=pool->PuddleSize;
  116.  
  117.         /* And add it to the list */
  118.         AddHead((struct List *)&pool->PuddleList,(struct Node *)&mh->mh_Node);
  119.         /* Fall through to get the memory */
  120.         }
  121.         /* Try to get the memory */
  122.         ret=Allocate(mh,memSize);
  123.  
  124.         /* Got it? */
  125.         if(ret!=NULL)
  126.         break;
  127.  
  128.         /* No. Try next MemHeader */
  129.         mh=(struct MemHeader *)mh->mh_Node.ln_Succ;
  130.     }
  131.     /* Allocate does not clear the memory! */
  132.     if(pool->Requirements&MEMF_CLEAR)
  133.     {
  134.         ULONG *p=(ULONG *)ret;
  135.  
  136.         /* Round up (clearing longs is faster than just bytes) */
  137.         memSize=(memSize+sizeof(ULONG)-1)/sizeof(ULONG);
  138.  
  139.         /* NUL the memory out */
  140.         while(memSize--)
  141.         *p++=0;
  142.     }
  143.     }
  144.     /* Everything fine */
  145.     return ret;
  146.     __AROS_FUNC_EXIT
  147. } /* AllocPooled */
  148.  
  149.